<?php

namespace app\tools;

use app\exception\CustomException;
use OSS\OssClient;
use think\Config;
use think\Db;

class Helper
{
    //生成唯一的uuid
    public static function uuid() {
        mt_srand ( ( double ) microtime () * 10000 );
        $charid = strtoupper ( md5 ( uniqid ( rand (), true ) ) ); //根据当前时间（微秒计）生成唯一id.
        $hyphen = chr ( 45 ); // "-"
        $uuid = '' . //chr(123)// "{"
            substr ( $charid, 0, 8 ) . $hyphen . substr ( $charid, 8, 4 ) . $hyphen . substr ( $charid, 12, 4 ) . $hyphen . substr ( $charid, 16, 4 ) . $hyphen . substr ( $charid, 20, 12 );
        //.chr(125);// "}"
        return $uuid;
    }

    //生成随机数字
    public static function smsCode($length = 4, $type = 1) {
        $n = 0;
        $chars = [];

        if ((int)$length < 1)
            $length = 1;

        switch($type) {
            case 1:
                $n = 9;
                $chars = [0,1,2,3,4,5,6,7,8,9];
                break;
            case 2:
                $n = 25;
                $chars = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
                break;
            case 3:
                $n = 25;
                $chars = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
                break;
            case 4:
                $n = 35;
                $chars = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'];
                break;
            case 5:
                $n = 35;
                $chars = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
                break;
            default;
                $n = 9;
                $chars = [0,1,2,3,4,5,6,7,8,9];
                break;
        }
        $code = '';
        for ($i=0;$i<$length;$i++) {
            $code .= $chars[mt_rand(0,$n)];
        }

        return $code;
    }

    //验证session是否过期,因为tp5里面不能单独设置session有效市场
    public static function checkSession($session) {
        if (empty($session))
            return false;
        if (!isset($session['createTime']) || !isset($session['time']))
            return true;
        if (time() < ($session['createTime'] + $session['time']))
            return true;
        return false;
    }

    //生成订单sn
    public static function createOrderSn() {
        $str1 = date("YmdHis");
        list($msec, $sec) = explode(' ', microtime());
        $str2 = round(($msec + $sec) * 1000);
        return $str1.str_pad(rand(1,10000),5,'0',STR_PAD_LEFT).substr($str2, 6,strlen($str2));
    }


//算年纪
    public static function  birthday($birthday){
        $age = strtotime($birthday);
        if($age === false){
          return false;
        }

        list($y1,$m1,$d1) = explode("-",date("Y-m-d",$age));
        $now = strtotime("now");

        list($y2,$m2,$d2) = explode("-",date("Y-m-d",$now));
        $age = $y2 - $y1;

        if((int)($m2.$d2) < (int)($m1.$d1))
            $age -= 1;

        return $age;
    }

    /**
     * 获取微信用户的详情
     *
     * @access public
     * @param string $code 微信的code
     * @return array
     */
    public static function getWxUserInfo($code) {
        $wxChatInfo = Config::get("wechat");
        $accessInfo = self::getWxChatAccessToken($code, $wxChatInfo);
        $userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=".$accessInfo["accessToken"]."&openid=".$accessInfo["openId"]."&lang=zh_CN";
        $userInfo = Curl::get_request_payload($userInfoUrl, []);
        if (empty($userInfo) || strpos($userInfo, 'errcode') || strpos($userInfo, 'errmsg')) {
            throw new CustomException("WECAHAT_CURL_ERROR");
        }
        //$userInfo = json_decode($userInfo, true);
        return json_decode($userInfo, true);
    }
    /**
     * 获取参数
     *
     * @access public
     * @param string $code 微信的code
     * @return array
     */
    public static function getWxChatAccessToken($code, $wxChatInfo) {
        $appId = $wxChatInfo["app_id"];
        $secret = $wxChatInfo["secret"];
        $accessTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$appId."&secret=".$secret."&code=".$code."&grant_type=authorization_code";
        $accessToken = Curl::get_request_payload($accessTokenUrl, []);
        if (empty($accessToken) || strpos($accessToken, 'errcode') || strpos($accessToken, 'errmsg')) {
            throw new CustomException("WECAHAT_CURL_ERROR");
        }

        $accessToken = json_decode($accessToken, true);
        if (!isset($accessToken["access_token"]) || !isset($accessToken["openid"])) {
            throw new CustomException("WECAHAT_CURL_ERROR");
        }
        $data = [
            "accessToken"=> $accessToken["access_token"],
            "openId"=> $accessToken["openid"],
            "unionId"=> isset($accessToken["unionId"]) ? $accessToken["unionId"] : ''
        ];
        return $data;
    }

    /**
     * OSS文件上传
     *
     * @access public
     * @param string $filePath 文件的路劲
     * @param string $fileName 文件的名称
     * @param string $bucket 文件的bucket
     * @return array
     */
    public static function uploadOss($filePath, $fileName, $bucket) {
        $ossConfig = Config::get("oss");
        $accessKeyId = $ossConfig["key"];
        $accessKeySecret = $ossConfig["secret"];
        $endpoint = $ossConfig["endpoint"];
        empty($bucket) && $bucket = $ossConfig["bucket"];
        $ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
        $res = $ossClient->uploadFile($bucket, $fileName, $filePath);
        return $res;
    }

    /**
     * OSS文件上传
     *
     * @access public
     * @param string $inputName 上传文件的名字
     * @param string $savePath 保存的路劲
     * @param string $bucket 文件的bucket
     * @param array $ext 限制上传文件的类型
     * @param integer $size 限制上传文件的大小
     * @return array
     */
    public static function uploadImage($inputName, $savePath = '', $size = 10240, $ext = ['jpg', 'png', 'gif', 'jpeg', 'bmp'], $bucket = '') {
        $file = request()->file($inputName);
        if (empty($file)) {
            throw new CustomException("UPLOAD_FILE_EMPTY");
        }

        $fileInfo = $file->getInfo();

        //判断文件大小
        if (floor($fileInfo["size"]/1024) > $size) {
            throw new CustomException("UPLOAD_FILE_ERROR");
        }
        //判断文件类型是否正确
        $fileExt = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
        if (!in_array($fileExt, $ext)) {
            throw new CustomException("UPLOAD_FILE_ERROR");
        }

        $fileName = empty($savePath) ? date('Ymd') . DS . md5(microtime(true)) .".". $fileExt : $savePath . DS . date('Ymd') . DS . md5(microtime(true)) .".".  $fileExt;
        $info = self::uploadOss($fileInfo["tmp_name"], $fileName, $bucket);

        if (!isset($info["oss-request-url"])) {
            throw new CustomException("UPLOAD_FAIL");
        }

        return $info;
    }

    //给用户发送消息
    public static function sendMessage($userInfo, $data = []) {
        if (!isset($userInfo["sendType"]))
            return false;

        $templateInfo = Db::name("message_template")
            ->field(["title", "content"])
            ->where(["type"=> $userInfo["sendType"], "user_type"=> $userInfo["type"], "status"=> 1])
            ->find();
        if (!empty($templateInfo)) {
            $pattern = [];
            $replacement = [];
            foreach ($data as $key=>$value) {
                $pattern[] = "#\{\\$(".$key.")\}#";
                $replacement[] = $value;
            }
            if (!empty($pattern)) {
                $templateInfo["content"] = preg_replace($pattern, $replacement, $templateInfo["content"]);
            }
            return Db::name("message")->insertGetId([
                "title"=> $templateInfo["title"],
                "uid"=> $userInfo["sendUid"],
                "type"=> 1,
                "user_type"=> $userInfo["type"],
                "content"=> $templateInfo["content"],
            ]);
        }
        return true;
    }
}